﻿using SqlSugar;
using SunnyPaine.Autofac.Extension.SqlSugar.Context;
using SunnyPaine.Autofac.Extension.SqlSugar.Util;
using System.Collections.Generic;
using System.Data;

namespace SunnyPaine.Autofac.Extension.SqlSugar.Repository
{
    /// <summary>
    /// 提供 SqlSugar 基础的公共操作，该操作支持多租户事务。
    /// </summary>
    /// <typeparam name="T">数据实体类型。</typeparam>
    public abstract class BaseSqlSugarTenant<T> : IBaseSqlSugar<T> where T : class, new()
    {
        private readonly PropertyInfoParser<T> parser;
        private ISqlSugarClient sqlSugarClient;

        /// <summary>
        /// 配置Id。
        /// </summary>
        public virtual string ConfigId { get; set; }

        #region 构造方法
        /// <summary>
        /// 使用默认参数创建 <see cref="BaseSqlSugarTenant{T}"/> 的实例。
        /// </summary>
        public BaseSqlSugarTenant(ISqlSugarClient sqlSugarClient)
        {
            this.parser = new PropertyInfoParser<T>();
            this.sqlSugarClient = sqlSugarClient;
        }
        #endregion


        #region 私有方法
        /// <summary>
        /// 从数据库连接的本地线程 <see cref="DBAContext"/> 中获取 <see cref="ISqlSugarClient"/> 的实例。
        /// 该数据库连接贯穿业务逻辑层和数据访问层。
        /// </summary>
        /// <returns></returns>
        protected ISqlSugarClient GetClient()
        {
            ISqlSugarClient client = DBAContext.GetClient(this.ConfigId);
            if (client != null)
            {
                return client;
            }
            if (!string.IsNullOrEmpty(this.ConfigId) && this.sqlSugarClient is SqlSugarScope)
            {
                return ((SqlSugarScope)this.sqlSugarClient).GetConnection(this.ConfigId);
            }
            return this.sqlSugarClient;
        }

        /// <summary>
        /// 从数据库连接的本地线程 <see cref="DBAContext"/> 中获取 <see cref="SimpleClient{T}"/> 的实例。
        /// 该数据库连接贯穿业务逻辑层和数据访问层。
        /// </summary>
        /// <returns></returns>
        protected SimpleClient<T> GetSimpleClient()
        {
            return this.GetClient().GetSimpleClient<T>();
        }
        #endregion


        #region 公共方法，基本CRUD操作
        /// <summary>
        /// 新增数据。
        /// </summary>
        /// <param name="entity"></param>
        public virtual bool Insert(T entity)
        {
            return this.GetSimpleClient().Insert(entity);
        }

        /// <summary>
        /// 批量新增数据。
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual bool InsertRange(List<T> entities)
        {
            return this.GetSimpleClient().InsertRange(entities);
        }

        /// <summary>
        /// 新增或更新数据。
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool InsertOrUpdate(T entity)
        {
            return this.GetSimpleClient().InsertOrUpdate(entity);
        }

        /// <summary>
        /// 批量新增或更新数据。
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual bool InsertOrUpdate(List<T> entities)
        {
            return this.GetSimpleClient().InsertOrUpdate(entities);
        }

        /// <summary>
        /// 删除指定数据。
        /// </summary>
        /// <param name="id"></param>
        public virtual bool DeleteById(dynamic id)
        {
            return this.GetSimpleClient().DeleteById(id);
        }

        /// <summary>
        /// 批量删除指定数据。
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public virtual bool DeleteByIds(dynamic[] ids)
        {
            return this.GetSimpleClient().DeleteByIds(ids);
        }

        /// <summary>
        /// 修改数据。
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool UpdateById(T entity)
        {
            return this.GetSimpleClient().Update(entity);
        }
        #endregion

        #region 公共方法，IBaseSqlSugar成员
        /// <summary>
        /// 获取基础的 Select 操作。
        /// </summary>
        /// <returns></returns>
        public ISugarQueryable<T> Selector()
        {
            return this.GetClient().Queryable<T>();
        }

        /// <summary>
        /// 查询所有数据。
        /// </summary>
        /// <returns></returns>
        public virtual List<T> SelectAll()
        {
            return this.Selector().ToList();
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 使用SQL语句查询。
        /// </summary>
        /// <param name="sql">sql语句。</param>
        /// <param name="parameters">参数。</param>
        /// <returns></returns>
        public virtual List<T> SelectBySql(string sql, object parameters)
        {
            DataTable dt = this.GetClient().Ado.GetDataTable(sql, parameters);
            return this.parser.DataTable2List(dt);
        }

        /// <summary>
        /// 使用SQL语句查询
        /// </summary>
        /// <param name="sql">sql语句。</param>
        /// <param name="parameters">参数列表。</param>
        /// <returns></returns>
        public virtual List<T> SelectBySql(string sql, List<SugarParameter> parameters)
        {
            DataTable dt = this.GetClient().Ado.GetDataTable(sql, parameters);
            return this.parser.DataTable2List(dt);
        }

        /// <summary>
        /// 使用SQL语句查询。
        /// </summary>
        /// <param name="sql">sql语句。</param>
        /// <param name="parameters">可变长参数列表。</param>
        /// <returns></returns>
        public virtual List<T> SelectBySql(string sql, params SugarParameter[] parameters)
        {
            DataTable dt = this.GetClient().Ado.GetDataTable(sql, parameters);
            return this.parser.DataTable2List(dt);
        }

        /// <summary>
        /// 查询指定数据。
        /// </summary>
        /// <param name="id">主键。</param>
        /// <returns></returns>
        public virtual T SelectById(object id)
        {
            return this.Selector().InSingle(id);
        }
        #endregion
    }
}
